package database

import (
	"gitee.com/jjawesomejj/awesome-util/config"
	"gitee.com/jjawesomejj/awesome-util/helper/commonhelper"
	"gitee.com/jjawesomejj/awesome-util/helper/timeHelper"
	"gorm.io/gorm"
	"reflect"
	"time"
)

type Model interface {
	TableName() string
}
type BaseModel struct {
	CreateTime string `json:"create_time"`
	UpdateTime string `json:"update_time"`
	DeleteTime int    `json:"delete_time"`
}

type ExtParamsModel interface {
	GetExtParams(key string, defaultValue string) string
}

func (baseModel *BaseModel) TableName() string {
	return ""
}

func (response *PageResponse) ExtendRows(fun func(row map[string]interface{}) map[string]interface{}) {
	isSlice := reflect.ValueOf(response.List).Kind() == reflect.Slice
	if isSlice {
		for index, row := range response.List {
			response.List[index] = fun(row)
		}
	}
}

func (baseModel *BaseModel) AutoSave(model Model, data map[string]interface{}) error {
	dataStr := commonhelper.JsonEncode(data)
	err := commonhelper.JsonDecodeWithType(dataStr, &model)
	if err != nil {
		return err
	} else {
		res := GetDbConnection().Table(model.TableName()).Save(model)
		return res.Error
	}

}

type PageResponse struct {
	Page     int                      `json:"page"`
	Total    int64                    `json:"total"`
	PageSize int                      `json:"page_size"`
	List     []map[string]interface{} `json:"list"`
}

func (baseModel *BaseModel) Pager(query *gorm.DB, page int, pageSize int, totalQuery *gorm.DB) (PageResponse, error) {
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 30
	}
	var list []map[string]interface{}
	var total int64
	if totalQuery != nil {
		result := totalQuery.Select("count(1) as num").Count(&total)
		if result.Error != nil {
			return PageResponse{}, result.Error
		}
	} else {
		result := query.Count(&total)
		if result.Error != nil {
			return PageResponse{}, result.Error
		}
	}
	result := query.Limit(pageSize).Offset(pageSize * (page - 1)).Find(&list)
	if result.Error != nil {
		return PageResponse{}, result.Error
	}
	data := PageResponse{
		Page:     page,
		PageSize: pageSize,
		Total:    total,
		List:     list,
	}
	data.ExtendRows(func(row map[string]interface{}) map[string]interface{} {
		keys := []string{
			"create_time",
			"update_time",
		}
		for _, key := range keys {
			if value, ok := row[key]; ok {
				timeValue := value.(time.Time)
				row[key] = timeHelper.TimeParseString(timeValue)
			}
		}
		return row
	})
	return data, nil
}

func (baseModel *BaseModel) RowByID(id int, model Model) error {
	GetDbConnection().
		Table(model.TableName()).
		Where("id", id).
		Where("delete_time", 0).First(&model)
	return nil
}

func (baseModel *BaseModel) RowsByIDs(models interface{}, tableName string, ids []int) (interface{}, error) {
	GetDbConnection().
		Table(tableName).
		Where("id in ?", ids).
		Where("delete_time", 0).Find(&models)
	return models, nil
}

func GetExtParams(model ExtParamsModel, key string, defaultValue interface{}, checkValueFunc func(value interface{}) (interface{}, bool)) interface{} {
	value := model.GetExtParams(key, "")
	if v, ok := checkValueFunc(value); ok {
		return v
	}
	configValue := config.GetConfigByKey(key, func() interface{} {
		return nil
	})
	if v, ok := checkValueFunc(configValue); ok {
		return v
	}
	return defaultValue
}

//
//func (baseModel *BaseModel) BeforeUpdate(tx *gorm.DB) (err error) {
//	return nil
//}
//
//// 在同一个事务中更新数据
//func (baseModel *BaseModel) AfterUpdate(tx *gorm.DB) (err error) {
//	return nil
//}
